package org.sgx.gwtsjcltest.client.test;

import org.junit.Test;
import org.sgx.gwtsjcl.client.BitArrayType;
import org.sgx.gwtsjcl.client.EncryptParam;
import org.sgx.gwtsjcl.client.SJCL;
import org.sgx.gwtsjcl.embedded.SJCLEmbedded;
import org.sgx.jsutil.client.JsObject;
import org.sgx.jsutil.client.JsUtil;

import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * meant to be runned inheriting SJCLEmbedded
 * 
 * @author sg
 * 
 */
public class GWTTest1Case extends GWTTestCase {
	@Override
	public String getModuleName() {
		return "org.sgx.gwtsjcltest.GWTSJCLEmbeddedTest";
	}

	
	private SJCL c;

	@Override
	protected void gwtSetUp() throws Exception {
		super.gwtSetUp();
		SJCLEmbedded.loadScript();
		c = SJCL.sjcl();
	}

	@Test
	public void testRandom() {
		c.random().addEntropy(31, 2, "number");
		JsArrayInteger a1 = c.random().randomWords(10);
		JsArrayInteger a2 = c.random().randomWords(10);
		for (int i = 0; i < a1.length(); i++) {
//			System.out.println("testRandom: "+a1.get(i));
			assertTrue(a1.get(i) != a2.get(i));
			// System.out.println(a1.get(i));
		}
		// System.out.println("SEE: "+JsUtil.dumpObj(a1, true));
	}

	@Test
	public void testSha256() {
		String s = "don quijote de la mancha";
		BitArrayType ba1 = toBitArray(s);
		// System.out.println("a1: "+c.hash().sha256().hash(s)+" - "+c.hash().sha256().hash(ba1));
		// assertEquals(c.hash().sha256().hash(s), c.hash().sha256().hash(ba1));
		assertEquals(toString(c.hash().sha256().hash(s)), toString(c.hash().sha256().hash(s)));
		assertEquals(toString(c.hash().sha256().hash(ba1)), toString(c.hash().sha256().hash(ba1)));
		// System.out.println(toString(c.hash().sha256().hash(ba1)));
	}

	@Test
	public void testBase64() {
		String s = "don quijote de la mancha";
		BitArrayType ba1 = toBitArray(s);
		// System.out.println("SEE123333: "+JsUtil.dumpObj(ba1, true));
		String encoded = c.codec().base64().fromBits(ba1);
		// System.out.println("ENCO: "+encoded);
		BitArrayType decoded = c.codec().base64().toBits(encoded);
		// System.out.println("decoded: "+JsUtil.dumpObj(decoded, true));
		String decodedStr = toString(decoded);
		// System.out.println("decodedStr: "+decodedStr);
		assertEquals(s, decodedStr);
	}

	@Test
	public void testBitArray() {
		String s = "don quijote de la mancha";
		BitArrayType ba1 = toBitArray(s);
		BitArrayType ba2 = toBitArray(s);
		assertTrue(c.bitArray().equal(ba1, ba2));
		
		assertTrue(s.equals(toString(ba1))); 
	}
	
	@Test
	public void testHex() {
		String s = "don quijote de la mancha";		
		String hex1 = c.codec().hex().fromBits(toBitArray(s));
		String s2 = toString(c.codec().hex().toBits(hex1));
		assertEquals(s, s2); 
	}
	@Test
	public void testUTF8String() {
		String s = "don quijote de la mancha";		
		String hex1 = c.codec().utf8String().fromBits(toBitArray(s)); 
		String s2 = toString(c.codec().utf8String().toBits(hex1));
		assertEquals(s, s2); 
	}
	@Test
	public void testHashSha256() {
		String s = "don quijote de la mancha";		
		BitArrayType hash1 = c.hash().sha256().hash("don quijote de la mancha");
		BitArrayType hash2 = c.hash().sha256().hash("2don quijote de la mancha2");
		System.out.println(hash1+" - "+hash2);
		assertNotSame(hash1, hash2); 
	}

	@Test
	public void testEncrypt() {
String s = "don quijote de la mancha", p = "psswd1";
assertEquals(c.decrypt(p, c.encrypt(p, s)), s);
	}
	
	@Test
	public void testJSON() {
		String json1 = "{\"p\": \"foo\"}";
		JsObject obj1 = c.json().decode(json1).cast();
		assertTrue(obj1.objGetString("p").equals("foo")); 
		
		String json2 = c.json().encode(obj1); 
		JsObject obj2 = c.json().decode(json2).cast();
		assertTrue( obj2.objGetString("p").equals("foo"));
		
		String encrypted1 = c.json().encrypt("secret123", json1);
		String decrypted = c.json().decrypt("secret123", encrypted1); 
		
		JsObject obj3 = c.json().decode(decrypted).cast(); 
		assertEquals("foo", obj3.objGetString("p")); 
	}
	
	
	private String toString(BitArrayType a) {
		byte[] b = new byte[a.length()];
		for (int i = 0; i < a.length(); i++) {
			b[i] = (byte) a.get(i);
		}
		return new String(b);
	}

	private BitArrayType toBitArray(String s) {
		BitArrayType jsa = JsArrayInteger.createArray().cast();
		byte[] a = s.getBytes();
		for (int i = 0; i < a.length; i++) {
			jsa.push(a[i]);
		}
		return jsa;
	}

	
	
}
